package com.scpii.api.common.auth.token;

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;

import com.scpii.api.common.Constants;
import com.scpii.api.common.auth.AuthorizationRequest;
import com.scpii.api.common.auth.ClientAuthentication;
import com.scpii.api.common.auth.client.ClientDetailsService;
import com.scpii.api.common.auth.thirdparty.ThirdPartyAuthenticationToken;
import com.scpii.api.common.exception.InvalidRequestException;
import com.scpii.api.common.exception.InvalidUserException;
import com.scpii.api.util.DateUtil;

public class ThirdPartyTokenGranter extends AbstractTokenGranter {

	public static final String GRANT_TYPE = "thirdparty";

	private final AuthenticationManager authenticationManager;

	public ThirdPartyTokenGranter(AuthenticationManager authenticationManager,
			AuthorizationServerTokenServices tokenServices,
			ClientDetailsService clientDetailsService) {
		super(tokenServices, clientDetailsService, GRANT_TYPE);
		this.authenticationManager = authenticationManager;
	}

	@Override
	protected ClientAuthentication getClientAuthentication(
			AuthorizationRequest clientToken) {

		Map<String, String> parameters = clientToken
				.getAuthorizationParameters();
		String username = parameters.get("username");
		String token = parameters.get("token");
		Date tokenTimeOut = DateUtil.parseDate(parameters.get("tokenTimeOut"));
		String loginType = parameters.get("loginType");
		String userAliasName = parameters.get("userAliasName");
		String userAvatar = parameters.get("userAvatar");
		String profiles = parameters.get("profiles");

		if (StringUtils.isBlank(username)) {
			throw new InvalidRequestException("username must be provide ");
		}

		if (StringUtils.isBlank(loginType)) {
			throw new InvalidRequestException("loginType must be provide ");
		}

		Authentication userAuth = new ThirdPartyAuthenticationToken(username,
				Constants.USER_DEFAULT_PSSWORD, token, tokenTimeOut, loginType,
				userAliasName, userAvatar, profiles);
		try {
			userAuth = authenticationManager.authenticate(userAuth);
		} catch (BadCredentialsException e) {
			throw new InvalidUserException(e.getMessage());
		}
		if (userAuth == null || !userAuth.isAuthenticated()) {
			throw new InvalidUserException("Could not authenticate user: "
					+ username);
		}

		return new ClientAuthentication(clientToken, userAuth);

	}
}
